package com.ssm.jdbc;

import org.springframework.util.CollectionUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static com.ssm.jdbc.DateUtil.YYYY_MM_DD_HH_MM_SS;

public class DelSeqTask {
    public static final String MAX_CREATE_DATE = "2022-01-01";

    public static void main(String[] args) {

        List<DbConfig> dbConfigs = dbConfigList();
        List<DbDataSource> dbConnList = new ArrayList<>();
        for (int i = 0; i < dbConfigs.size(); i++) {
            DbConfig item = dbConfigs.get(i);
            try {
                Connection connection = JdbcUtil.getConnection(item.getUrl(), item.getUser(), item.getPassword());
                DbDataSource dbConn = new DbDataSource(connection, "order_seq_" + (i + 1));
                dbConn.setLimit(5000);
                dbConnList.add(dbConn);
            } catch (SQLException e) {
                System.err.println("url:" + item.getUrl() + ",user:" + item.getUser() + ",password:" + item.getPassword());
                throw new RuntimeException(e);
            }
        }

        String maxCreateDate = MAX_CREATE_DATE;
        if (args != null && args.length > 0) {
            maxCreateDate = args[0];
        }
        ExecutorService executorService = Executors.newFixedThreadPool(32);
        CountDownLatch countDownLatch = new CountDownLatch(dbConnList.size());
        String finalMaxCreateDate = maxCreateDate;

        //Map<String, Long> lastIdMap = new ConcurrentHashMap<>();
        dbConnList.forEach(dbConn -> {
            executorService.submit(() -> {
                Long minId = 0L;
                Connection conn = dbConn.getConnection();
                String connName = dbConn.getConnName();
                Integer limit = dbConn.getLimit();
                try {
                    for (int i = 0; true; i++) {
                        long startTime = System.currentTimeMillis();
                        String querySql = "select f_id from t_order_sequence where f_id > " + minId + " and `f_create_date` < '" + finalMaxCreateDate + "' order by id asc limit " + limit;
                        List<Order> orderList = JdbcUtil.query(querySql, conn, Order.class, (rs, obj) -> {
                            List<Order> oList = new ArrayList<>();
                            ResultSet resultSet = (ResultSet) rs;
                            try {
                                while (resultSet.next()) {
                                    Order order = new Order();
                                    order.setId(resultSet.getLong(1));
                                    oList.add(order);
                                }
                            } catch (Throwable t) {
                                t.printStackTrace();
                            } finally {
                                JdbcUtil.release(resultSet, null, null);
                            }
                            return oList;
                        });
                        if (CollectionUtils.isEmpty(orderList)) {
                            break;
                        } else {
                            int idx = orderList.size() - 1;
                            minId = orderList.get(idx).getId();
                            if (i % 1000 == 0) {
                                sout("删除数据, 参数信息 id:" + minId + ",limit:" + limit + ",date:" + finalMaxCreateDate + ",size:" + orderList.size() + ".");
                            }
                            /*
                            if (Objects.equals(lastIdMap.getOrDefault(connName, Long.MIN_VALUE), minId)) {
                                // 删除完毕，两次的 minId 相同
                                break;
                            }
                            lastIdMap.put(connName, minId);
                             */
                        }
                        String ids = orderList.stream().map(o -> String.valueOf(o.getId())).collect(Collectors.joining(","));
                        String executeSql = "delete from t_order_sequence where id in (" + ids + ")";
                        JdbcUtil.execute(executeSql, conn);
                        Long cost = System.currentTimeMillis() - startTime;
                        if (cost > 500) {
                            sout("删除数据, 执行耗时 db: " + connName + ",id:" + minId + ",limit:" + limit + ",size:" + orderList.size() + ",cost:" + cost + ".");
                            sout("删除数据, 执行耗时 db: " + connName + ",cost:" + cost + ",sql:" + querySql + ".");
                        }
                        Thread.sleep(5);

                        if (i >= Integer.MAX_VALUE - 1) {
                            i = 0;
                        }
                    }
                } catch (Throwable t) {
                    t.printStackTrace();
                    System.err.println("发生异常，异常信息: " + t.getMessage());
                } finally {
                    countDownLatch.countDown();
                }
                System.out.println("删除完毕, dbName:" + connName);
            });
        });
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        dbConnList.forEach(conn -> JdbcUtil.release(null, null, conn.getConnection()));
        System.out.println("所有的数据删除完毕");
    }

    private static List<DbConfig> dbConfigList() {
        List<DbConfig> dbConfigList = new ArrayList<>();

        //seq1 -seq9
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3326.hwc-bj.huobiidc.com:3326/linear_order_seq1",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3327.hwc-bj.huobiidc.com:3327/linear_order_seq2",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3328.hwc-bj.huobiidc.com:3328/linear_order_seq3",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3330.hwc-bj.huobiidc.com:3330/linear_order_seq4",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3331.hwc-bj.huobiidc.com:3331/linear_order_seq5",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3332.hwc-bj.huobiidc.com:3332/linear_order_seq6",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3333.hwc-bj.huobiidc.com:3333/linear_order_seq7",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3334.hwc-bj.huobiidc.com:3334/linear_order_seq8",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3335.hwc-bj.huobiidc.com:3335/linear_order_seq9",
                "linear_order_seq_usrc", "G5bWyJ_EVtjaqnJD"));

        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3326.hwc-bj.huobiidc.com:3326/linear_futures_order_seq1",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3327.hwc-bj.huobiidc.com:3327/linear_futures_order_seq2",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3328.hwc-bj.huobiidc.com:3328/linear_futures_order_seq3",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3329.hwc-bj.huobiidc.com:3329/linear_futures_order_seq4",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3331.hwc-bj.huobiidc.com:3331/linear_futures_order_seq5",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3332.hwc-bj.huobiidc.com:3332/linear_futures_order_seq6",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3333.hwc-bj.huobiidc.com:3333/linear_futures_order_seq7",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3334.hwc-bj.huobiidc.com:3334/linear_futures_order_seq8",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));
        dbConfigList.add(new DbConfig("jdbc:mysql://master-loadtest-3335.hwc-bj.huobiidc.com:3335/linear_futures_order_seq9",
                "linear_futures_order_seq_usrc", "D7zFuru_HnL45b2T"));

        return dbConfigList;
    }

    private static void sout(String str) {
        System.out.println(DateUtil.formatBySimpleDateFormat(new java.util.Date(), YYYY_MM_DD_HH_MM_SS) + ":" + str);
    }
}

class OrderSeq {
    private Long fId;

    public Long getfId() {
        return fId;
    }

    public void setfId(Long fId) {
        this.fId = fId;
    }
}
